package com.yxj.lib_exo;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;

/**
 * 评论list view
 */
public class PLListView extends LinearLayout {

    private View view;
    private RecyclerView recyclerView;
    private PlListener plListener ;

    public PLListView(Context context) {
        this(context, null);
    }

    public PLListView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PLListView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        addView(view = LayoutInflater.from(context).inflate(R.layout.pl_list_layout, this, false));
        recyclerView = view.findViewById(R.id.mRecyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(context));
        view.findViewById(R.id.layTitle).setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_MOVE:
                        moveY = event.getRawY() - dy;
                        if (moveY > 0 ) {
                            setTranslationY(moveY);
                        }
                        break;

                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL:
                    case MotionEvent.ACTION_OUTSIDE:
                        if (moveY>0){
                            closeOrOpen();
                        }
                        break;
                }
                return true;
            }
        });
    }


    /**
     * @param layoutId
     * @param l
     * @param <T>
     */
    public <T> void setData(@LayoutRes int layoutId, List<T> l,PlListener<T> plListener) {
        if (layoutId == 0)
            return;

        if (l == null || l.isEmpty())
            return;

        list.clear();
        list.addAll(l);
        view.findViewById(R.id.layTitle).setMinimumWidth(getMeasuredWidth());
        this.plListener=plListener;
        recyclerView.setAdapter(adapter = new PLAdapter(layoutId, list));
    }


    @SuppressLint("NotifyDataSetChanged")
    public <T> void addData(List<T> l) {
        if (l == null || l.isEmpty())
            return;

        list.addAll(l);

        if (adapter != null) {
            adapter.notifyDataSetChanged();
        }
    }


    private PLAdapter adapter;
    private List<Object> list = new ArrayList<>();

    private class PLAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        private List<T> list;
        private int layoutId;

        public PLAdapter(int layoutId, List<T> list) {
            this.list = list;
            this.layoutId = layoutId;
        }

        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            return new PLViewHolder(LayoutInflater.from(parent.getContext()).inflate(layoutId, null));
        }

        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
            if (PLListView.this.plListener!=null){
                PLListView.this.plListener.bindView(holder,list.get(position),position);
            }
        }

        @Override
        public int getItemCount() {
            return list.size();
        }
    }

    private static class PLViewHolder extends RecyclerView.ViewHolder {

        public PLViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }


    /**
     * 检测是否滑动顶部了
     *
     * @return
     */
    private boolean isRecyclerViewAtTop() {
        if (recyclerView == null || recyclerView.getChildCount() == 0) {
            return true; // 空列表视为在顶部
        }

        LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
        if (layoutManager == null) {
            return false;
        }

        // 检查第一个可见项位置是否为0
        int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
        if (firstVisibleItemPosition != 0) {
            return false;
        }

        // 检查第一个可见项是否完全显示
        View firstVisibleChild = layoutManager.findViewByPosition(firstVisibleItemPosition);
        if (firstVisibleChild == null) {
            return false;
        }

        // 如果第一个可见项的顶部与RecyclerView的顶部对齐，则认为已滚动到顶部
        return firstVisibleChild.getTop() == recyclerView.getPaddingTop();
    }


    private float dy;
    private float moveY;
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                getParent().requestDisallowInterceptTouchEvent(true);
                dy = ev.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                moveY = ev.getRawY() - dy;
                return moveY > ViewConfiguration.getTouchSlop() && isRecyclerViewAtTop();
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                moveY = event.getRawY() - dy;
                if (moveY > 0 && isRecyclerViewAtTop()) {
                    setTranslationY(moveY);
                    callBackDrag(moveY/getMeasuredHeight());
                }
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_OUTSIDE:
                if (moveY>0){
                    closeOrOpen();
                }
                break;
        }
        return true;
    }


    /**
     * 是关闭还是还原
     */
    private void closeOrOpen() {
        float r = moveY / getMeasuredHeight();
        if (r >= 0.3) {
            closePL(moveY,getMeasuredHeight());
        } else {
            openPl(moveY,0);
        }
    }


    private void openPl(float moveY, int i) {
        ValueAnimator v = ValueAnimator.ofInt((int) moveY, i);
        v.setDuration(300);
        v.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(@NonNull ValueAnimator animation) {
                int t = (int) animation.getAnimatedValue();
                setTranslationY(t);
                callBackDrag(t*1.0f/getMeasuredHeight());
            }
        });
        v.start();
    }

    private void closePL(float moveY, int measuredHeight) {
        ValueAnimator v = ValueAnimator.ofInt((int) moveY, measuredHeight);
        v.setDuration(300);
        v.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                setVisibility(GONE);
                setTranslationY(0);
                callBackDrag(1);
            }
        });
        v.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(@NonNull ValueAnimator animation) {
                int t = (int) animation.getAnimatedValue();
                setTranslationY(t);
                callBackDrag(t*1.0f/getMeasuredHeight());
            }
        });
        v.start();
    }


    /**
     *
     * @param r
     */
    private void callBackDrag(float r){
        if (plListener!=null)
        {
            plListener.dragPlView(r);
        }
    }


    public interface PlListener<T>{

        /**
         * @param holder
         * @param position
         */
        void bindView( RecyclerView.ViewHolder holder,T item, int position);


        /**
         * 当前拖拽系数
         * @param r
         */
        void dragPlView(float r);
    }

}
